#ifndef LIN_AL_H
#define LIN_AL_H
#include <stdbool.h>
#include <assert.h>
#include <stdint.h>

#ifdef DEBUG
# define debug_fprintf(x)	fprintf x
#else
# define debug_fprintf(x)	((void) 0)
#endif

struct matrix {
	double **data;
	int m; /* rows */
	int n; /* columns */
	bool _is_allocated;
	double determinant;
};

/*
 * Self-explanatory
 */
void swap_rows(struct matrix *, int, int);
void swap_cols(struct matrix *, int, int);

/*
 * Multiply row (column) in first arg by second arg
 * and put it into row (column) given in third arg
 */
void multiply_add_rows(struct matrix *, unsigned int, double, unsigned int);
void multiply_add_cols(struct matrix *, unsigned int, double, unsigned int);

/*
 * Calculate determinant of matrix
 */
double det(struct matrix *);
struct matrix *gauss(struct matrix *);

/*
 * Various debugging and helper functions
 */
void fprint_matrix(struct matrix *, FILE *);
void *my_malloc(size_t); /* TODO inline */
void *my_calloc(size_t, size_t); /* TODO inline */
int matrix_calloc(struct matrix *);
void matrix_free(struct matrix *);
#endif
